/*
 * Copyright (C) 2012 Tomas Shestakov. <http://code.google.com/p/jmmo/>
 */

package jmmo.engine.property

/**
 * Implements methods for add/remove listeners and fire event for observables which are not chain.
 * @author Tomas Shestakov
 */
trait ObservableListenersSupport extends ChangeListeners {

  /**
   * Add the specified change listener. Filter is ignored because this `Observable` has not children.
   * @param listener a `PartialFunction[ChangeEvent, Unit]` which gets [[jmmo.engine.property.ChangeEvent]] and executes a code with it.
   * @param filter is ignored because this `Observable` has not children.
   */
  def addChangeListener(listener: Listener, filter: Filter = Identifiable.passAll) {
    listeners += listener
  }

  /**
   * Remove the specified change listener.
   * @param listener a `PartialFunction[ChangeEvent, Unit]` which gets [[jmmo.engine.property.ChangeEvent]] and executes a code with it.
   */
  def removeChangeListener(listener: Listener) {
    listeners -= listener
  }

  /**
   * Sends the specified event to all listeners.
   * @param event event to send
   */
  def fireChangeEvent(event: ChangeEvent) {
    listeners foreach (jmmo.util.applyIfDefined(_, event))
  }

  /**
   * Contains listeners of the observable.
   */
  protected var listeners = Set.empty[Listener]
}

/**
 * Implements `ObservableValue.serializableCopy` method for [[jmmo.engine.property.ObservableValue]]
 * @tparam A type of `ObservableValue` value
 * @author Tomas Shestakov
 */
trait SerializableSilentObservableValueSupport[+A] extends ObservableValue[A] {

  def serializedCopy(filter: Identifiable.Filter = Identifiable.passAll) = SilentObservableValue(this(), id)
}

/**
 * Base trait for creation [[jmmo.engine.property.Property]] instances.
 * @tparam A type of `Property` value
 * @author Tomas Shestakov
 */
trait PropertySupport[A] extends Property[A] with ObservableListenersSupport with SerializableSilentObservableValueSupport[A]
